#include "attack.hpp"

using namespace Shiny;
using namespace Shiny::Applejack;

Attack::Attack(bool& canLaid, Fixture* fixture) : fixture(fixture), canLaid(canLaid)
{
    if (fixture)
	SetFixture(fixture);
    damage = 10;
}

void Attack::SetFixture(Fixture* fixture)
{
    this->fixture = fixture;
    contactBegin  = fixture->ContactBegin.Connect(*this, &Attack::BeginCollision);
    contactEnd    = fixture->ContactEnd.Connect(*this, &Attack::EndCollision);
    fixtureDestroyed = fixture->Destroyed.Connect(*this, &Attack::UnsetFixture);
}

void Attack::UnsetFixture(Fixture*)
{
    if (fixture)
    {
	fixture->ContactBegin.Disconnect(contactBegin);
	fixture->ContactEnd.Disconnect(contactEnd);
	fixture->Destroyed.Disconnect(fixtureDestroyed);
	fixture = 0;
    }
}

void Attack::SetCollision(b2Contact* contact, bool value)
{
    if (!fixture)
	return ;
    std::list<Target>::iterator it  = targets.begin();
    std::list<Target>::iterator end = targets.end();
    b2Fixture*                  other;
    Fixture*                    otherFix;

    other    = (contact->GetFixtureA() == *fixture ? contact->GetFixtureB() : contact->GetFixtureA());
    otherFix = Fixture::GetFixture(other);
    for (; it != end ; ++it)
    {
	if ((it->fixture) == otherFix)
	{
	    it->collision = value;
	    break ;
	}
    }
    std::cout << "End Attack Set Collision" << std::endl;
}

void Attack::operator()(void)
{
  if (canLaid)
  {
    std::list<Target>::iterator it  = targets.begin();
    std::list<Target>::iterator end = targets.end();

    for (; it != end ; ++it)
    {
	if (it->collision)
	{
	    it->Hit.Emit(damage, effects);
	    canLaid = false;
	}
    }
  }
}
